package com.ming_za.od_updater_sdk.processing.update;

import com.ming_za.od_updater_sdk.IUpdater;
import com.ming_za.od_updater_sdk.server_api.ServerAPIState;
import com.ming_za.od_updater_sdk.event.PostUpdateEvent;
import com.ming_za.od_updater_sdk.event.UpdateErrorEvent;
import com.ming_za.od_updater_sdk.event.UpdatingEvent;
import com.ming_za.od_updater_sdk.exception.FileUnableDeleteException;
import com.ming_za.od_updater_sdk.exception.UnConnectServerException;
import com.ming_za.od_updater_sdk.obj.ReqValue;
import com.ming_za.od_updater_sdk.obj.Res;
import com.ming_za.od_updater_sdk.server_api.result_obj.data.ResFileInfo;
import com.ming_za.od_updater_sdk.obj.UpdateError;
import java.io.*;
import java.nio.file.Files;

/**
 * 资源更新任务
 */
public class UpdateTaskRunnable implements Runnable{

    /**
     * 文件处理器
     */
    private final IUpdater odUpdater;

    /**
     * 当前更新的资源
     */
    private final Res res;

    /**
     * 当前更新资源的版本号
     */
    private final int version;

    public UpdateTaskRunnable(IUpdater odUpdater, Res res, int version) {
        this.odUpdater = odUpdater;
        this.res = res;
        this.version = version;
    }

    @Override
    public void run() {
        odUpdater.getLogger().debug("启动线程更新资源-->" + res.getResPath());
        Exception exception = null;

        long fileSize = 0;

        //开始单个资源更新

        File file;
        try {
            file = odUpdater.getFileProcessor().getFile(odUpdater.getRootDirectory(), res);

            if (!res.isDelete()){
                //当资源为"非删除类型"时

                //从服务器获取文件下载
                ReqValue<ResFileInfo> resFile;
                do {

                    try {
                        resFile = odUpdater.getUpdaterServerAPI().getResFile(res,odUpdater);

                        if (resFile.getServerAPIState() == ServerAPIState.MAXIMUM_DOWNLOAD){
                            odUpdater.getLock().lock();
                            odUpdater.reducePoolSize();
                            odUpdater.getCondition().await();
                            odUpdater.getLock().unlock();
                        }else if (resFile.getServerAPIState() == ServerAPIState.SUCCESS){
                            break;
                        }else {
                            throw new UnConnectServerException("获取资源下载失败");
                        }
                    } catch (InterruptedException e) {
                        odUpdater.getLock().unlock();
                        return;
                    }
                }while (true);

                fileSize = resFile.getValue().getFileSize();

                odUpdater.getLogger().info("正在下载资源-->[资源ID:" + res.getId() + "]");

                //数据传输
                try (InputStream inputStream = resFile.getValue().getInputStream(); OutputStream outputStream = Files.newOutputStream(file.toPath())) {
                    odUpdater.getUpdateHandler().update(new UpdatingEvent(res, version,fileSize, inputStream, outputStream));
                    odUpdater.getFileUtils().transmitFile(inputStream, outputStream,fileSize,res,odUpdater);
                } finally {
                    //关闭Response
                    resFile.getValue().getResponse().close();
                }

            }else {

                //当资源为"删除类型"时
                if (file.exists()){
                    odUpdater.getLogger().info("正在删除文件->" + res.getResPath());
                    if (!file.delete()){
                        throw new FileUnableDeleteException("文件无法删除" + res.getResPath());
                    }
                }
            }

        } catch (Exception e) {
            exception = e;
        }

        if (exception == null){
            odUpdater.getLogger().info("资源更新完成->" + res.getResPath());
            //更新完成
            odUpdater.getUpdateHandler().postUpdate(new PostUpdateEvent(res,version,fileSize));
        }else {
            odUpdater.getLogger().warn("资源更新出现异常->" + res.getResPath(),exception);
            odUpdater.getUpdateHandler().updateError(new UpdateErrorEvent(res,version,exception));
            odUpdater.addUpdateError(new UpdateError(res,exception));
        }

        //记录一次完成
        odUpdater.addEndTask();
    }
}
